<template>
  <div>
    <div>
      <div class="chat-body">
        <div class="left-layout" v-if="displayHistory">
          <div class="type-info" >
            <img src="./static/images/head.png" style="width: 40px;height: 40px" alt=""/>
            <div>
              <h2>{{"&nbsp;"}}{{ info.name }}</h2>
            </div>
          </div>
          <div class="new-chat" @click="newMessage">
            <i class="el-icon-edit-outline"></i>
            {{"&nbsp;"}}开启新对话
          </div>
          <div style="color: #ccc;font-size: 14px;margin-left: 10px">
            历史对话
          </div>
          <div style="height: 76vh;overflow-y: auto">
            <div style="padding-bottom: 60px">
              <div v-for="(item) in messageList" @click="listSelect(item)" :key="item.id">
                <div v-if="chatInfo.conversationId===item.id" class="history-chat ok-chat-list-item ok-chat-list-item-select" @mouseenter="item.more=true" @mouseleave="item.more=false;item.operate=false">
                  {{ $ok.tool.text_format(item.name,8) }}
                  <div class="list-more" @click.stop="item.operate=!item.operate" v-if="item.more">
                    <i class="el-icon-more"></i>
                  </div>
                  <div v-if="item.operate" class="more-operate">
                    <el-button icon="el-icon-edit" size="mini" style="width: 90px;margin-left: 0;border: none;text-align: left" @click.stop="inputDialogToggle(item)">重命名</el-button>
                    <el-button icon="el-icon-delete-solid" size="mini" style="width: 90px;margin-left: 0;border: none;text-align: left" @click.stop="del(item)">删除</el-button>
                  </div>
                </div>
                <div v-else class="ok-chat-list-item history-chat" @mouseenter="item.more=true" @mouseleave="item.more=false;item.operate=false">
                  {{ $ok.tool.text_format(item.name,8) }}
                  <div class="list-more" @click.stop="item.operate=!item.operate" v-if="item.more">
                    <i class="el-icon-more"></i>
                  </div>
                  <div v-if="item.operate" class="more-operate">
                    <el-button icon="el-icon-edit" size="mini" style="width: 90px;margin-left: 0;border: none;text-align: left" @click.stop="inputDialogToggle(item)">重命名</el-button>
                    <el-button icon="el-icon-delete-solid" size="mini" style="width: 90px;margin-left: 0;border: none;text-align: left" @click.stop="del(item)">删除</el-button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="right-layout" style="display: flex;justify-content: center;align-items: center" v-if="showPre">
          <div style="" v-if="Object.keys(parameters).length">
            <pre_information :info="info" :meta="meta" :parameters="parameters" @getInputs="getInputs"></pre_information>
          </div>
        </div>
        <div class="right-layout" v-else>
          <div class="chat-info" id="chatInfo">
            <div class="chat-top">
              <h3>{{ $ok.tool.text_format(chatInfo.name,20) }}</h3>
            </div>
            <div class="chat-background">
              <div class="chat-main" id="chatMain">
                <div style="">
                  <div v-if="parameters.opening_statement">
                    <div class="ok-box-flex">
                      <div class="ok-box-center-left answer">{{ parameters.opening_statement }}</div>
                      <div class="ok-width-max"></div>
                    </div>
                  </div>
                  <div class="line-20"></div>
                  <div v-for="(item) in message" :key="item.id">
                    <div v-if="item.query">
                      <div class="ok-box-flex">
                        <div class="ok-width-max"></div>
                        <div class="ok-box-center-right query">{{ item.query }}</div>
                      </div>
                      <div class="line-20"></div>
                      <div class="chat-answer">
<!--                        <div class="ok-box-flex">-->
<!--                          <div class="ok-box-center-left answer" style="display: block" v-html="getMdHtml(item.answer)"></div>-->
<!--                          <div class="ok-width-max"></div>-->
<!--                        </div>-->
                        <div class="answer" style="white-space: normal;" v-html="getMdHtml(item.answer)"></div>
                        <div class="chat-hidden">
                          <el-tooltip class="item" effect="dark" content="复制" placement="top">
                            <i class="el-icon-copy-document" @click="copyAnswer(item)"
                               style="cursor: pointer;background-color: white;border: 1px solid lightgray;border-radius: 5px;padding: 5px">
                            </i>
                          </el-tooltip>
                        </div>
                      </div>
                      <div class="line-20"></div>
<!--                      <div class="answer" v-html="getMdHtml(item.answer)"></div>-->

                    </div>
                  </div>
                </div>
              </div>
            </div>

          </div>
          <div class="chat-input" id="chatInput" v-if="displayInput">
            <div class="input-background">
              <div class="input-border">
                <div class="inputDeep">
                  <el-input type="textarea" v-model="chatInfo.query" :autosize="{ minRows: 1, maxRows: 5}" placeholder="Enter发送，Shift+Enter换行，来说点什么吧" ></el-input>
                  <div style="display: flex;margin-top: 10px">
                    <div style="flex: 1">
                    </div>
                    <div class="send-btn" @click="postData()" v-if="sendStatus==='send'">
                      <img src="./static/images/up.png" style="width: 28px;height:28px;margin-left: 6px;margin-top: 6px" alt=""/>
                    </div>
                    <div class="send-btn" v-if="sendStatus==='loading'">
                      <div style="color: white;line-height: 40px;text-align: center">
                        <i class="el-icon-loading"></i>
                      </div>

                    </div>
                    <div class="send-btn" @click="stop" v-if="sendStatus==='answer'">
                      <div class="white-block">
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <div class="input-foot">
                内容由 AI 生成，请仔细甄别
              </div>
            </div>
          </div>

        </div>
      </div>
    </div>

<!--    <uni-popup ref="inputDialog" type="dialog">-->
<!--      <uni-popup-dialog ref="inputClose"  mode="input" title="输入内容"-->
<!--                        placeholder="请输入新的名称" @confirm="rename"></uni-popup-dialog>-->
<!--    </uni-popup>-->

  </div>
</template>

<script>
import MarkdownIt from "markdown-it";
import Pre_information from "@/components/ok-chat/com/pre_information.vue";

export default {
  name: 'ok-chat',
  // eslint-disable-next-line vue/no-unused-components
  components: {Pre_information},
  props: {
    // eslint-disable-next-line vue/require-prop-type-constructor
    appUuid: "",
    displayHistory:{
      default:true,
    },
    displayInput:{
      default:true,
    },
    conversationId:{
      default: null,
    }
  },
  data() {
    return {
      showPre: true,
      task_id: "",
      visible: false,
      parameters: {},
      meta:{},
      info:{},
      config: {
        backgroundColor: '#F7F8FAFF',
        title: "",
      },
      deep:false,
      sendStatus:"send",
      message: [],
      messageList: [],
      renameMessageInfo: {},
      chatInfo: {
        name:"",
        conversationId: "",
        appUuid: "",
        query: "",
        inputs: {},
        files: {},
      },
      cnversationsRequest: {
        conversation_id: "",
        last_id: "",
        limit: 100,
        sort_by: "",
        appUuid: "",
      },
      messagesRequest: {
        conversation_id: "",
        first_id: "",
        limit: 100,
        appUuid: "",
      },
      resizeObserver:null
    };
  },
  mounted() {
    this.init();
    //开始键盘按下监听
    window.addEventListener('keydown',this.keyDown);

  },
  beforeDestroy() {
    //在页面销毁前将ResizeObserver 销毁
    if (this.resizeObserver) {
      this.resizeObserver.disconnect();
    }
    //移除键盘监听
    window.removeEventListener('keydown',this.keyDown)
  },
  methods: {
    init() {
      this.apiConversations();
      this.getParameters();
      this.getMeta();
      this.getInfo();
      // this.createResizeObserver();
      //基本信息
      //配置信息
    },
    //获取inputs
    getInputs(e){
      this.chatInfo.inputs = e;
      this.newMessage();
      this.showPre = false;
      if (!this.resizeObserver){
        this.$nextTick(() =>{
          this.createResizeObserver();
        })
      }
    },
    //获取应用参数
    getParameters(){
      this.$api.chat.parameters(this.appUuid).then(res =>{
        this.parameters = res.result;
      })
    },
    //获取应用Meta信息
    getMeta(){
      this.$api.chat.meta(this.appUuid).then(res =>{
        this.meta = res.result;
      })
    },
    getInfo(){
      this.$api.chat.info(this.appUuid).then(res =>{
        this.info = res.result;
      })
    },
    // 重命名输入框
    inputDialogToggle(item){
      this.renameMessageInfo = item;
      this.$refs.inputDialog.open()
    },
    //重命名
    rename(name){
      let _data ={
        appUuid: this.appUuid,
        conversation_id: this.renameMessageInfo.id,
        auto_generate:false,
        name:name
      };
      //重命名对话的名字
      this.$api.chat.rename(_data).then(res =>{
        //刷新对话列表
        this.apiConversations();
        if (this.chatInfo.conversationId === _data.conversation_id){
          this.chatInfo.name = res.result.name
        }
      })
    },

    //删除对话
    del(item){
      this.$confirm("确定删除？", '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(()=>{
        let _data = {
          appUuid: this.appUuid,
          conversation_id: item.id
        };
        this.$api.chat.del(_data).then(()=>{
          this.apiConversations();
          if (_data.conversation_id===this.chatInfo.conversationId){
            this.message = [];
            this.chatInfo.conversationId = "";
            this.chatInfo.name = "";
            this.chatInfo.query = "";
            this.chatInfo.files = {};
            this.chatInfo.inputs = {};
            this.showPre = true
          }
        })
      })
    },

    //停止响应
    stop(){
      let _data = {
        task_id: this.task_id,
        appUuid:this.appUuid,
      };
      this.$api.chat.stop(_data).then(() =>{

      })
    },

    //监听键盘enter和shift+enter
    keyDown(e){
      if (e.key==="Enter"&&!e.shiftKey){
       e.preventDefault();
       this.postData();
      }
    },

    //复制回答
    copyAnswer(item){
      let tempDiv = document.createElement('div');
      tempDiv.innerHTML = this.getMdHtml(item.answer);
      let copyText = tempDiv.textContent || tempDiv.innerText;
      this.$ok.tool.copy(copyText);
    },

    //创建输入框的监听
    createResizeObserver() {
      // let info = document.getElementById("chat-info");
      let info = document.getElementById("chatMain");
      this.resizeObserver = new ResizeObserver(entries => {
        for (let entry of entries) {
          let height = entry.contentRect.height + 10
          info.style.paddingBottom = height + "px"
        }
      });
      let chatInput = document.getElementById('chatInput');
      if (chatInput){
        this.resizeObserver.observe(chatInput);
      }
    },
    //对话选择
    listSelect(item) {
      this.chatInfo.conversationId = item.id;
      // this.chatInfo.inputs = item.inputs;
      this.apiMessages(this.chatInfo.conversationId);
      this.chatInfo.name = item.name;
      this.sendStatus = "send"
    },
    // 获取对话列表
    apiConversations() {
      this.cnversationsRequest.appUuid = this.appUuid;
      this.$api.chat.conversations(this.cnversationsRequest).then(res => {
        this.messageList = res.result.data;
        this.messageList = this.messageList.map(item =>{
          return {
            ...item,
            operate: false,
            more: false
          }
        });
        if (this.conversationId){
          this.messageList.forEach((item)=>{
            if (item.id===this.conversationId){
              this.listSelect(item);
            }
          })
        }
      });
    },
    // 获取历史消息
    apiMessages(id) {
      this.messagesRequest.appUuid = this.appUuid;
      this.messagesRequest.conversation_id = id;
      this.$api.chat.messages(this.messagesRequest).then(res => {
        this.message = res.result.data;
        if (this.message.length>0){
          this.chatInfo.inputs = this.message[this.message.length-1].inputs;
          this.showPre = false;
        }
        if (!this.resizeObserver){
          this.$nextTick(() =>{
            this.createResizeObserver();
          })
        }
      });
    },
    // 发送消息并获取答案
    postData() {
      if (!this.chatInfo.query) {
        this.$ok.tool.message.error("请输入内容！")
        return;
      }
      if (this.sendStatus !== "send") {
        this.$ok.tool.message.error("请等待回答完毕！")
        return;
      }
      this.sendStatus = "loading"
      let index = 0;  //标记
      let conversation_id = ""; //对话的id
      this.chatInfo.appUuid = this.appUuid;
      //获取消息展示的dom元素
      let chatInfo = document.getElementById("chatInfo");
      //在对话记录push新元素
      this.message.push({
        query: this.chatInfo.query,
        answer: "ok-loading",
      })
      // 将新消息滚动到可视窗口
      this.$nextTick(()=>{
        chatInfo.scrollTop = chatInfo.scrollHeight-chatInfo.clientHeight;
      })
      var _this = this;
      let _formData = {...this.chatInfo};
      //清空输入内容
      this.chatInfo.query = "";
      //调用接口发送消息
      this.$api.chat.send(
          _formData,
          {
            open: () => {
            },
            message: (msg) => {
              if (msg.event === "message") {
                try {
                  var data = JSON.parse(msg.data);
                  if (data.event === "message") {
                    // 判断是不是第一次，第一次的话将conversation_id赋值
                    if (index===0){
                      this.sendStatus = "answer"
                      _this.task_id = data.task_id;
                      conversation_id = data.conversation_id;
                      _this.message[_this.message.length - 1].answer = "";
                      index++;
                    }
                    // 持续的添加到页面
                    _this.message[_this.message.length - 1].answer = _this.message[_this.message.length - 1].answer + data.answer;
                  }
                  // 判断当前是否是在页面的底部200px内的位置，是的话就滚动到底部
                  if (chatInfo.scrollHeight-chatInfo.scrollTop-chatInfo.clientHeight<200){
                    chatInfo.scrollTop = chatInfo.scrollHeight-chatInfo.clientHeight;
                  }
                } catch (e) {
                  console.log(e)
                }
              }
            },
            close: () => {
              this.sendStatus = "send";
              //判断是否是第一条信息
              if (_this.message.length === 1){
                // 赋值conversationId
                _this.chatInfo.conversationId = conversation_id;
                let _data ={
                  appUuid:_this.appUuid,
                  conversation_id:conversation_id,
                  auto_generate:false,
                  name:_this.message[0].query
                };
                //重命名对话的名字
                _this.$api.chat.rename(_data).then(res =>{
                  //刷新对话列表
                  _this.apiConversations();
                  _this.chatInfo.name = res.result.name;
                })
              }
            },
            error: (err) => {
              console.log(err)
            },
          }
      );
    },
    // 新建对话
    newMessage() {
      // 判断是否已经有一条新建对话
      // if (!this.messageList[0].id) return
      this.showPre = true;
      this.chatInfo.conversationId = "";
      this.message=[];
      this.messageList.unshift({
        id:"",
        name:"新对话",
        operate: false,
        more: false
      });
      this.chatInfo.name = "新对话"
    },
    getMdHtml(info) {
      const markdown = new MarkdownIt();
      var patt = /<details[\s\S]*details>/gm;
      var think = info.match(patt);
      // console.log(info);
      var thinkingHtml = "";
      var _html = "";
      if (think && think.length > 0) {
        // console.log(think[0]);
        thinkingHtml = think[0];
        var md = info.replace(thinkingHtml, "");
        _html = thinkingHtml + markdown.render(md);
      } else if (info.indexOf("details") >= 0) {
        _html = info;
      } else if (info==="ok-loading") {
        _html = `<i class="el-icon-loading"></i>`;
      }else {
        _html = markdown.render(info);
      }
      _html = _html.replace(/<hr>/g, "");
      _html = _html.replace("Thinking", "思考");
      return _html;
    }
  },

}
</script>

<style scoped>
.inputDeep>>>.el-input__inner {
  border: 0;
}
/* 如果你的 el-input type 设置成textarea ，就要用这个了 */
.inputDeep>>>.el-textarea__inner {
  border: 0;
  resize: none;/* 这个是去掉 textarea 下面拉伸的那个标志，如下图 */
}
.ok-chat-list-item {
  padding: 5px 10px 5px 10px;
  cursor: pointer;
}

.ok-chat-list-item-select {
  //background-color: #b8d5ff;
  background-color: #eeeefd;
  border-radius: 3px;
}
.chat-answer{
  position: relative;
}
.chat-hidden{
  width: 30px;
  height: 30px;
  position: absolute;
  top: -10px;
  right: 10px;
  display: none;
}
.chat-answer:hover .chat-hidden{
  display: block;
}
.query{
  //background-color: #b8d5ff;
  //background-color: #eeeefd;
  background-color: #dedefd;
  border-radius: 5px;
  padding: 10px;
}

.answer{
  background-color: #ffffff;
  border-radius: 5px;
  padding: 20px;
  margin-top: 10px;
  margin-bottom: 10px;
}

.chat-body{
  background-color: #f5f6f8;
  //padding: 1vh 20px;
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-content: center;
  /* border: 1px solid lightgray; */
  //box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
}
.left-layout {
  flex: 1;
  padding: 20px 0 20px 20px;
  border-right: 1px solid lightgray;
  background-color: white;
}
.right-layout{
  flex: 6;
  //display: flex;
  flex-direction: column;
  position: relative;
}
.type-info{
  padding: 10px 20px;
  display: flex;
}
.new-chat{
  width: 70%;
  border: 1px solid lightgray;
  padding: 10px 20px;
  margin: 20px 10px;
  text-align: left;
  border-radius: 10px;
}
.history-chat{
  width: 70%;
  border: 1px solid lightgray;
  padding: 10px 20px;
  margin: 20px 10px;
  text-align: left;
  border-radius: 10px;
  position: relative;
}
.list-more{
  position: absolute;
  right: 10px;
  top: 10px
}
.more-operate{
  width: 90px;
  position:absolute;
  bottom: -55px;
  right: 0;
  background-color: white;
  border: 1px solid lightgray;
  border-radius:5px;z-index: 2
}
.chat-info{
  flex: 1;
  position: relative;
  height: 100vh;
  overflow-y: auto;
//max-height: 58vh;
//overflow-y: auto;
}
.chat-top{
  background-color: rgba(255, 255, 255, 0.96);
  text-align: center;
  height: 60px;
  line-height: 60px;
  position: sticky;
  top: 0;
  left: 0;
  z-index: 10;
}
.chat-background{
  width: 100%;
  display: flex;
  justify-content: center
}
.chat-main{
  width: 40%;
  position: relative;
  padding-bottom: 160px;
}
.chat-input{
//background-color: #f5f6f8;
  position: absolute;
  bottom:0;
  max-height: 200px;
  width: 100%;
  overflow-y: hidden;
  display: flex;
  justify-content: center
}
.input-background{
  width: 45%;
  background-color: #f5f6f8;
}

.input-border{
  border-radius: 5px;
  border: 2px solid #e3e2e2;
  padding: 10px;
  background-color: white;
}
.send-btn{
  width: 40px;
  height: 40px;
  border-radius: 20px;

  background-color: #b4b4ec;
}
.input-foot{
  text-align: center;
  color: #c4bcbc;
  font-size: 14px;
}
.white-block{
  width: 16px;
  height:16px;
  margin-left: 12px;
  margin-top: 12px;
  background-color: white
}

.ok-box-flex {
  display: flex;
  flex-direction: row;
}

.ok-width-max {
  -webkit-flex: 1;
  flex: 1;
}
.ok-box-center-right {
  -webkit-justify-content: flex-end;
  justify-content: flex-end;
  -webkit-align-items: center;
  align-items: center;
  text-align: right;
  flex-direction: row;
  display: flex;
}
.ok-box-center-left {
  -webkit-align-items: center;
  align-items: center;
  flex-direction: row;
  text-align: left;
  display: flex;
}
</style>

